精度问题 内容 概述 精度概念 货币精度 价格表精度 数量精度 格式化 概述 每个会计都对数字有着专业的敏感,其职业生涯或者日常工作总会碰到精度问题。每个管理软件都有一堆无趣且无由的精度设置点,给设置和理解都带来一些困扰。所以单独把ID的精度问题拿出来讨论总结,避免拖泥带水。 常见取整差异场景有:单位转换,税价转换,汇率转换,如: 物品=矿泉水(1箱x12pc),供应商采购列表价格=10元,价格表单价=12/10=0.83元/pc 采购订单,明细输入一箱,自动转成12pc,明细总额=0.83*12=9.96元 差0.04元,每个系统都会碰到这样的问题。 总的来说,ID的精度原理简单,设置方便,基本上满足绝大多数应用场景。 精度概念 ID中有关精度的概念如下: 1. 货币精度:币种设置,系统关键精度定义。 2. 数量精度:计量单位设置,尽量定义小单位,以便使用大数量。 3. 价格精度:价格表设置。 口头上所说的“显示精度”,id没有概念对应。虽然能够对字段显示进行格式化,对无精度处理字段(比如价格输入字段),系统如实显示和存储。 还有如下小数点取整定义: 1. 价格取值:价格表模式明细页签中的价格取整设置。 取整方法 源值 取整值 不舍入 18.46 18.46 取10分 18.46 18.50 取整10 18.46 20 取整数 18.46 18 以5或9结尾 18.46 18.49 货币精度(1位) 18.46 18.5 货币精度 币种精度可以设置为“标准精度”和“成本精度”。 标准精度:会计事务和单据处理时的小数位舍入长度。比如:数量/金额合计精度、税额精度。 成本精度:成本计算时的小数位舍入长度。默认多数币种的成本精度=标准精度+2。 例子: 默认参数,标准精度=2,成本精度=4,价格表精度=2。 在单据中,采购价格输入5位小数,该价格显示为5位, 其他价格、合计字段则按“标准精度”显示为2位。 单据过账后,分录金额均为2位。 价格表精度 价格表精度,设置三个价格信息(列表价,标准价,限制价)的小数位,如果-1表示不取整,保留输入精度。 无论精度定义,价格表版本的价格字段可以输入任何长度数字,原值显示。 例子1(不影响自动生成价格精度): 产品-采购:采购列表价格=1.234 设置价格表模式明细的取整方式和价格表精度后,生成价格记录: 取整方式 不取整 货币精度=2 价格表精度=4 1.234 1.23 价格表精度=1 1.234 1.23 价格表精度=-1 1.234 1.23 例子2(影响单据的价格取值精度): 价格表版本: 标准价格=1.234 新建一个采购/销售订单,选择产品明细,自动填入价格表版本价格 订单明细 标准价格 价格合计(2个合计2.468,默认标准精度=2) 价格表精度=4 1.234 2.47 价格表精度=1 1.20 2.40 价格表精度=-1 1.234 2.47 以上看到,价格表精度对取值的影响,最后导致不同的产品合计金额。 数量精度 数量精度在“计量单位”中定义,且每个单位都拥有单独的“标准精度”和“成本计算精度”。 与价格不同的是,计量单位的标准精度影响输入数量的显示。 比如:单位的标准精度=0,数量输入1.1,显示为1;输入1.6,显示为2。 例子1(单位标准精度还影响单价) 单位:包,标准精度=3 单位转换:1包=12个 新建订单明细,数量输入1.2345,自动取整为1.235,这是完全正确。 价格输入10,单价计算为0.833,源自单位标准精度。 价格输入1,单价计算为1.00,默认货币标准精度是2。 似乎单位=包,数量只能输入整数,禁止输入小数,继续设置: 单位:包,标准精度=0,其他如上。 价格输入3,单价计算为0(3/12=0) 价格输入13,单价计算为1 (13/12=1) 这似乎是bug,单价计算应该取值“价格表精度”,而非“单位标准精度”。 退而求次,修改单位包的精度,或者直接修改单价字段的callout源代码。 https://groups.google.com/d/msg/idempiere/IWgx-P3hAPU/imFod2rTgrwJ 格式化 用户基本无需关心数据的存储定义,通常字段长度会大于所有精度。管理员可以在AD对象中对字段取值进行格式化方便阅读显示,或者自定义源代码满足特殊的小数取整要求。 参考:DisplayType.java